package topin.facecat.FaceCat.UI

import facecat.topin.core.FCColor
import facecat.topin.core.FCFont
import facecat.topin.core.FCInvokeEventCallBack
import facecat.topin.core.FCTouchInfo
import facecat.topin.div.FCMenu
import facecat.topin.grid.FCGrid
import facecat.topin.grid.FCGridCellStyle
import facecat.topin.grid.FCGridDoubleCell
import facecat.topin.grid.FCGridPercentCell
import facecat.topin.grid.FCGridRow
import facecat.topin.grid.FCGridStringCell
import facecat.topin.service.FCClientService
import facecat.topin.service.FCListenerMessageCallBack
import facecat.topin.service.FCMessage
import topin.facecat.FaceCat.UI.FCDraw.getPriceColor
import topin.facecat.FaceCat.Service.PriceDataServiceClient
import topin.facecat.FaceCat.Service.Security

/*
* 股票列表
*/
class SecurityList : FCGrid(), FCListenerMessageCallBack, FCInvokeEventCallBack{
    var m_requestID = -1

    /*
     *绑定代码
     *@param code
     */
    fun bindCodes(codes: ArrayList<Security?>) {
        m_rowsMap.clear()
        clearRows()
        update()
        selectedRows.clear()
        beginUpdate()
        for (i in codes.indices) {
            val security = codes[i]
            if (security!!.m_name.length > 0) {
                val row = GridRowEx()
                addRow(row)
                row.height = 25
                val showCode = security.m_code.substring(0, security.m_code.indexOf("."))
                row.tag = security.m_code
                row.addCell("colP0", FCGridNoCell())
                row.addCell("colP1", FCGridStringCell(showCode))
                row.addCell("colP2", FCGridStringCell(security.m_name))
                val priceCell = FCGridDoubleCellEx()
                priceCell.m_underLine = true
                row.addCell("colP3", priceCell)
                row.addCell("colP4", FCGridPercentCell())
                row.addCell("colP5", FCGridDoubleCellEx())
                row.addCell("colP9", FCGridUnitDoubleCell())
                row.addCell("colP10", FCGridUnitDoubleCell())
                row.addCell("colP11", FCGridDoubleCellEx())
                row.addCell("colP12", FCGridPECell())
                row.addCell("colP13", FCGridPercentCell())
                row.addCell("colP14", FCGridPercentCell())
                row.addCell("colP15", FCGridUnitLongCell())
                row.addCell("colP16", FCGridUnitLongCell())
                row.addCell("colP17", FCGridStringCell())
                row.addCell("colP18", FCGridDoubleCellEx())
                row.addCell("colP19", FCGridDoubleCellEx())
                row.addCell("colP20", FCGridDoubleCellEx())
                row.addCell("colP21", FCGridPercentCell())
                row.addCell("colP22", FCGridPercentCell())
                row.addCell("colP23", FCGridPercentCell())
                row.addCell("colP24", FCGridDoubleCell())
                m_rowsMap[security.m_code] = row
                for (j in 0 until row.m_cells.size) {
                    val cell = row.m_cells[j]
                    val cellStyle = FCGridCellStyle()
                    cell.style = cellStyle
                    if (j == 0 || j == 2) {
                        cellStyle.m_textColor = MyColor.USERCOLOR217
                    } else {
                        cellStyle.m_textColor = MyColor.USERCOLOR218
                    }
                }
            }
        }
        endUpdate()
        invalidate()
    }

    private val m_rowsMap = HashMap<String, FCGridRow>()

    /*
     * 跨线程调用
     *@param eventName
     *@param sender
     *@param args
     *@param invoke
     */
    override fun callInvokeEvent(eventName: String, sender: Any, args: Any, invoke: Any) {
        if (args != null) {
            val message = args as? FCMessage
            if (message != null) {
                if (message.m_serviceID == PriceDataServiceClient.SERVICEID) {
                    if (message.m_functionID == PriceDataServiceClient.FUNCTION_NEWDATA) {
                        val columnsMap = HashMap<String, Int>()
                        for (i in m_columns.indices) {
                            val gridColumn = m_columns[i]
                            columnsMap[gridColumn.name] = gridColumn.index
                        }
                        val columnIndex = ArrayList<Int?>()
                        columnIndex.add(columnsMap["colP3"])
                        columnIndex.add(columnsMap["colP4"])
                        columnIndex.add(columnsMap["colP5"])
                        columnIndex.add(columnsMap["colP9"])
                        columnIndex.add(columnsMap["colP10"])
                        columnIndex.add(columnsMap["colP11"])
                        columnIndex.add(columnsMap["colP12"])
                        columnIndex.add(columnsMap["colP13"])
                        columnIndex.add(columnsMap["colP14"])
                        columnIndex.add(columnsMap["colP15"])
                        columnIndex.add(columnsMap["colP16"])
                        columnIndex.add(columnsMap["colP17"])
                        columnIndex.add(columnsMap["colP18"])
                        columnIndex.add(columnsMap["colP19"])
                        columnIndex.add(columnsMap["colP20"])
                        columnIndex.add(columnsMap["colP21"])
                        columnIndex.add(columnsMap["colP22"])
                        columnIndex.add(columnsMap["colP23"])
                        columnIndex.add(columnsMap["colP24"])
                        val priceDatas = PriceDataServiceClient.getPriceDatas(
                            message.m_body,
                            message.m_bodyLength
                        )
                        for (i in priceDatas.indices) {
                            val priceData = priceDatas[i]
                            val code = priceData.m_code
                            if (m_rowsMap.containsKey(code)) {
                                val row = m_rowsMap[code]
                                val lastClose = priceData.m_lastClose
                                var diff = 0.0
                                var diffRange = 0.0
                                val close = priceData.m_close
                                if (close > 0) {
                                    diff = close - priceData.m_lastClose
                                }
                                if (close > 0 && priceData.m_lastClose !== 0.0) {
                                    diffRange = diff / priceData.m_lastClose
                                }
                                val cell3 = row!!.getCell(columnIndex[0]!!)
                                cell3.double = close
                                if (close > 0 && close == priceData.m_upperLimit) {
                                    cell3.m_style.m_backColor = FCColor.rgb(255, 82, 82)
                                    cell3.m_style.m_textColor = FCColor.Back
                                } else if (close > 0 && close == priceData.m_lowerLimit) {
                                    cell3.m_style.m_backColor = FCColor.rgb(82, 255, 82)
                                    cell3.m_style.m_textColor = FCColor.Back
                                } else {
                                    cell3.m_style.m_backColor = FCColor.None
                                    cell3.m_style.m_textColor = getPriceColor(close, lastClose)
                                }
                                val cell4 = row.getCell(columnIndex[1]!!)
                                cell4.double = diffRange
                                cell4.m_style.m_textColor = getPriceColor(close, lastClose)
                                val cell5 = row.getCell(columnIndex[2]!!)
                                cell5.double = diff
                                cell5.m_style.m_textColor = getPriceColor(close, lastClose)
                                val cell9 = row.getCell(columnIndex[3]!!)
                                cell9.double = priceData.m_volume / 100
                                val cell10 = row.getCell(columnIndex[4]!!)
                                cell10.double = priceData.m_amount
                                val cell11 = row.getCell(columnIndex[5]!!)
                                cell11.double = priceData.m_ratio
                                val cell12 = row.getCell(columnIndex[6]!!)
                                cell12.double = priceData.m_pe
                                var range = 0.0
                                if (lastClose != 0.0) {
                                    range =
                                        (priceData.m_high - lastClose) / lastClose - (priceData.m_low - lastClose) / lastClose
                                }
                                val cell13 = row.getCell(columnIndex[7]!!)
                                cell13.double = range
                                val cell14 = row.getCell(columnIndex[8]!!)
                                cell14.double = priceData.m_turnoverRate / 100
                                val cell15 = row.getCell(columnIndex[9]!!)
                                cell15.double = priceData.m_marketValue
                                val cell16 = row.getCell(columnIndex[10]!!)
                                cell16.double = priceData.m_flow
                                val cell17 = row.getCell(columnIndex[11]!!)
                                if (DataCenter.m_securityService!!.m_securitiesMap.containsKey(code)) {
                                    cell17.string =
                                        DataCenter.m_securityService!!.m_securitiesMap[code]!!.m_block
                                }
                                val cell18 = row.getCell(columnIndex[12]!!)
                                cell18.double = priceData.m_upperLimit
                                cell18.m_style.m_textColor =
                                    getPriceColor(priceData.m_upperLimit, lastClose)
                                val cell19 = row.getCell(columnIndex[13]!!)
                                cell19.double = priceData.m_lowerLimit
                                cell19.m_style.m_textColor =
                                    getPriceColor(priceData.m_lowerLimit, lastClose)
                            }
                        }
                        invalidate()
                    }
                }
            }
        } else {
            val securities = ArrayList<Security?>()
            for (i in m_rows.indices) {
                val row = m_rows[i]
                val sCode = row.tag.toString()
                if (DataCenter.m_securityService!!.m_securitiesMap.containsKey(sCode)) {
                    securities.add(DataCenter.m_securityService!!.m_securitiesMap[sCode])
                }
            }
            clearRows()
            update()
            invalidate()
            searchCodes(securities)
        }
    }

    /*
     * 回调方法
     *@param sender
     *@param message
     *@param invoke
     */
    override fun callListenerMessageEvent(sender: Any, message: FCMessage, invoke: Any) {
        this.invoke(message)
    }

    override fun delete() {
        if (!isDeleted) {
            DataCenter.m_priceDataServiceClient!!.removeListener(m_requestID)
            DataCenter.m_priceDataServiceClient!!.unSubCodes(m_requestID)
        }
        super.delete()
    }

    var m_menu: FCMenu? = null
    var m_clickLeftOrRight = false
    override fun onTouchDown(touchInfo: FCTouchInfo) {
        callTouchEvents("ontouchdown", touchInfo)
        if (!allowPreviewsEvent()) {
//            onDragScrollStart();
        }
        m_clickLeftOrRight = touchInfo.m_firstTouch
        touchEvent(touchInfo, 1)
    }

    var m_firstAdd = true
    override fun onAdd() {
        super.onAdd()
        if (m_firstAdd) {
            m_firstAdd = false
            addEvent(this, "oninvoke", this)
        }
    }

    fun searchCodes(securities: ArrayList<Security?>) {
        if (m_requestID != -1) {
            DataCenter.m_priceDataServiceClient!!.removeListener(m_requestID)
            DataCenter.m_priceDataServiceClient!!.unSubCodes(m_requestID)
        }
        bindCodes(securities)
        m_requestID = FCClientService.getRequestID()
        DataCenter.m_priceDataServiceClient!!.addListener(m_requestID, this, this)
        val sb = StringBuilder()
        for (security in securities) {
            sb.append(security!!.m_code + ",")
        }
        var codes = sb.toString()
        if (codes.endsWith(",")) {
            codes = codes.substring(0, codes.length - 1)
        }
        DataCenter.m_priceDataServiceClient!!.subCodes(m_requestID, codes)
    }

    /*
     * 第一次搜索代码
     */
    fun firstSearchCode() {
        val securities = ArrayList<Security?>()
        for (security in DataCenter.m_securityService!!.m_securities) {
            if (security.m_type !== 0) {
                securities.add(security)
            }
        }
        searchCodes(securities)
    }

    override fun onKeyDown(key: Char) {
        super.onKeyDown(key)
        m_isKeyDown = true
    }

    override fun onKeyUp(key: Char) {
        super.onKeyUp(key)
        m_isKeyDown = false
        if (m_searchCode.length > 0) {
            MainFrame.m_mainFrame.searchCode(m_searchCode)
        }
        m_searchCode = ""
    }

    var m_isKeyDown = false
    var m_searchCode = ""
    override fun onSelectedRowsChanged() {
        super.onSelectedRowsChanged()
        try {
            if (m_clickLeftOrRight) {
                if (selectedRows[0].m_cells.size > 0) {
                    val code = selectedRows[0].tag.toString()
                    if (m_isKeyDown) {
                        m_searchCode = code
                    } else {
                        MainFrame.m_mainFrame.searchCode(code)
                    }
                }
            }
        } catch (ex: Exception) {
        }
    }

    init {
        font = FCFont("Default", 14f)
    }
}
